Bug 113310.
authorSoeren Sandmann <sandmann@daimi.au.dk>
Fri, 9 Jul 2004 22:44:35 +0000 (22:44 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Fri, 9 Jul 2004 22:44:35 +0000 (22:44 +0000)
Sat Jul 10 00:37:45 2004  Soeren Sandmann  <sandmann@daimi.au.dk>

Bug 113310.

* gdk/x11/gdkwindow-x11.c (_gdk_x11_window_tmp_{un|re}set_bg):
New functions that can do a recursive unset/reset bg.

* gdk/x11/gdkgeometry-x11.c: Remove
gdk_window_tmp_{un|re}set_bg().

* gdk/x11/gdkwindow-x11.c (pre_unmap, post_unmap): New functions
called before and after unmapping a window. They unset the
background of all other windows to prevent flicker from the X
server repainting the background. post_unmap() also invalidates
the parent of the unmapped window to draw it without roundtrips.

* gdk/x11/gdkwindow-x11.c (show_window_internal): Unset
background of newly mapped windows and all desendants to prevent
flicker.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/x11/gdkgeometry-x11.c
gdk/x11/gdkwindow-x11.c
gdk/x11/gdkwindow-x11.h

index cd2cb7b3d63b661bea37f916314d890de25e4f97..9e6286cb853623c2b8397a5ebd11b76c8bf747d5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+Sat Jul 10 00:37:45 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       Bug 113310.
+       
+       * gdk/x11/gdkwindow-x11.c (_gdk_x11_window_tmp_{un|re}set_bg):
+       New functions that can do a recursive unset/reset bg.
+
+       * gdk/x11/gdkgeometry-x11.c: Remove
+       gdk_window_tmp_{un|re}set_bg().
+
+       * gdk/x11/gdkwindow-x11.c (pre_unmap, post_unmap): New functions
+       called before and after unmapping a window. They unset the
+       background of all other windows to prevent flicker from the X
+       server repainting the background. post_unmap() also invalidates
+       the parent of the unmapped window to draw it without roundtrips.
+
+       * gdk/x11/gdkwindow-x11.c (show_window_internal): Unset
+       background of newly mapped windows and all desendants to prevent
+       flicker.
+       
 Fri Jul  9 15:33:55 2004  Manish Singh  <yosh@gimp.org>
 
        * gdk/gdkevents.c: have a dummy case GDK_OWNER_CHANGE in switch
@@ -8,6 +28,8 @@ Fri Jul  9 15:33:55 2004  Manish Singh  <yosh@gimp.org>
 
 Fri Jul  9 23:26:09 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
 
+       (Bug 113340)
+
        * gdk/x11/gdkwindow-x11.h (struct _GdkWindowImplX11): Add an
        "override_redirect" bit.
 
index cd2cb7b3d63b661bea37f916314d890de25e4f97..9e6286cb853623c2b8397a5ebd11b76c8bf747d5 100644 (file)
@@ -1,3 +1,23 @@
+Sat Jul 10 00:37:45 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       Bug 113310.
+       
+       * gdk/x11/gdkwindow-x11.c (_gdk_x11_window_tmp_{un|re}set_bg):
+       New functions that can do a recursive unset/reset bg.
+
+       * gdk/x11/gdkgeometry-x11.c: Remove
+       gdk_window_tmp_{un|re}set_bg().
+
+       * gdk/x11/gdkwindow-x11.c (pre_unmap, post_unmap): New functions
+       called before and after unmapping a window. They unset the
+       background of all other windows to prevent flicker from the X
+       server repainting the background. post_unmap() also invalidates
+       the parent of the unmapped window to draw it without roundtrips.
+
+       * gdk/x11/gdkwindow-x11.c (show_window_internal): Unset
+       background of newly mapped windows and all desendants to prevent
+       flicker.
+       
 Fri Jul  9 15:33:55 2004  Manish Singh  <yosh@gimp.org>
 
        * gdk/gdkevents.c: have a dummy case GDK_OWNER_CHANGE in switch
@@ -8,6 +28,8 @@ Fri Jul  9 15:33:55 2004  Manish Singh  <yosh@gimp.org>
 
 Fri Jul  9 23:26:09 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
 
+       (Bug 113340)
+
        * gdk/x11/gdkwindow-x11.h (struct _GdkWindowImplX11): Add an
        "override_redirect" bit.
 
index cd2cb7b3d63b661bea37f916314d890de25e4f97..9e6286cb853623c2b8397a5ebd11b76c8bf747d5 100644 (file)
@@ -1,3 +1,23 @@
+Sat Jul 10 00:37:45 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       Bug 113310.
+       
+       * gdk/x11/gdkwindow-x11.c (_gdk_x11_window_tmp_{un|re}set_bg):
+       New functions that can do a recursive unset/reset bg.
+
+       * gdk/x11/gdkgeometry-x11.c: Remove
+       gdk_window_tmp_{un|re}set_bg().
+
+       * gdk/x11/gdkwindow-x11.c (pre_unmap, post_unmap): New functions
+       called before and after unmapping a window. They unset the
+       background of all other windows to prevent flicker from the X
+       server repainting the background. post_unmap() also invalidates
+       the parent of the unmapped window to draw it without roundtrips.
+
+       * gdk/x11/gdkwindow-x11.c (show_window_internal): Unset
+       background of newly mapped windows and all desendants to prevent
+       flicker.
+       
 Fri Jul  9 15:33:55 2004  Manish Singh  <yosh@gimp.org>
 
        * gdk/gdkevents.c: have a dummy case GDK_OWNER_CHANGE in switch
@@ -8,6 +28,8 @@ Fri Jul  9 15:33:55 2004  Manish Singh  <yosh@gimp.org>
 
 Fri Jul  9 23:26:09 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
 
+       (Bug 113340)
+
        * gdk/x11/gdkwindow-x11.h (struct _GdkWindowImplX11): Add an
        "override_redirect" bit.
 
index cd2cb7b3d63b661bea37f916314d890de25e4f97..9e6286cb853623c2b8397a5ebd11b76c8bf747d5 100644 (file)
@@ -1,3 +1,23 @@
+Sat Jul 10 00:37:45 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       Bug 113310.
+       
+       * gdk/x11/gdkwindow-x11.c (_gdk_x11_window_tmp_{un|re}set_bg):
+       New functions that can do a recursive unset/reset bg.
+
+       * gdk/x11/gdkgeometry-x11.c: Remove
+       gdk_window_tmp_{un|re}set_bg().
+
+       * gdk/x11/gdkwindow-x11.c (pre_unmap, post_unmap): New functions
+       called before and after unmapping a window. They unset the
+       background of all other windows to prevent flicker from the X
+       server repainting the background. post_unmap() also invalidates
+       the parent of the unmapped window to draw it without roundtrips.
+
+       * gdk/x11/gdkwindow-x11.c (show_window_internal): Unset
+       background of newly mapped windows and all desendants to prevent
+       flicker.
+       
 Fri Jul  9 15:33:55 2004  Manish Singh  <yosh@gimp.org>
 
        * gdk/gdkevents.c: have a dummy case GDK_OWNER_CHANGE in switch
@@ -8,6 +28,8 @@ Fri Jul  9 15:33:55 2004  Manish Singh  <yosh@gimp.org>
 
 Fri Jul  9 23:26:09 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
 
+       (Bug 113340)
+
        * gdk/x11/gdkwindow-x11.h (struct _GdkWindowImplX11): Add an
        "override_redirect" bit.
 
index 08af4c22d738c67c7b5ce5db29eb8499ef04bba3..3620495212db72449c147deea50eccf1306b2893 100644 (file)
 #include "gdkinternals.h"
 #include "gdkscreen-x11.h"
 #include "gdkdisplay-x11.h"
+#include "gdkwindow-x11.h"
 
 typedef struct _GdkWindowQueueItem GdkWindowQueueItem;
 typedef struct _GdkWindowParentPos GdkWindowParentPos;
@@ -183,8 +184,6 @@ static void gdk_window_postmove           (GdkWindow          *window,
 static void gdk_window_queue_translation  (GdkWindow          *window,
                                           gint                dx,
                                           gint                dy);
-static void gdk_window_tmp_unset_bg       (GdkWindow          *window);
-static void gdk_window_tmp_reset_bg       (GdkWindow          *window);
 static void gdk_window_clip_changed       (GdkWindow          *window,
                                           GdkRectangle       *old_clip,
                                           GdkRectangle       *new_clip);
@@ -324,7 +323,7 @@ gdk_window_guffaw_scroll (GdkWindow    *window,
   parent_pos.x11_y += new_info.y;
   parent_pos.clip_rect = new_info.clip_rect;
 
-  gdk_window_tmp_unset_bg (window);
+  _gdk_x11_window_tmp_unset_bg (window, FALSE);;
 
   if (dx > 0 || dy > 0)
     gdk_window_queue_translation (window, MAX (dx, 0), MAX (dy, 0));
@@ -361,7 +360,7 @@ gdk_window_guffaw_scroll (GdkWindow    *window,
                     impl->position_info.width, impl->position_info.height);
   
   if (impl->position_info.no_bg)
-    gdk_window_tmp_reset_bg (window);
+    _gdk_x11_window_tmp_reset_bg (window, FALSE);
   
   impl->position_info = new_info;
   
@@ -548,7 +547,7 @@ _gdk_window_move_resize_child (GdkWindow *window,
                         new_info.x, new_info.y, new_info.width, new_info.height);
       
       if (impl->position_info.no_bg)
-       gdk_window_tmp_reset_bg (window);
+       _gdk_x11_window_tmp_reset_bg (window, FALSE);
 
       if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj))
        XMapWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
@@ -594,7 +593,7 @@ _gdk_window_move_resize_child (GdkWindow *window,
        }
 
       if (impl->position_info.no_bg)
-       gdk_window_tmp_reset_bg (window);
+       _gdk_x11_window_tmp_reset_bg (window, FALSE);
 
       if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj))
        XMapWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
@@ -854,7 +853,7 @@ gdk_window_postmove (GdkWindow          *window,
     XMapWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window));
 
   if (impl->position_info.no_bg)
-    gdk_window_tmp_reset_bg (window);
+    _gdk_x11_window_tmp_reset_bg (window, FALSE);
 
   impl->position_info = new_info;
 
@@ -1063,56 +1062,6 @@ _gdk_window_process_expose (GdkWindow    *window,
   gdk_region_destroy (clip_region);
 }
 
-static void
-gdk_window_tmp_unset_bg (GdkWindow *window)
-{
-  GdkWindowImplX11 *impl;
-  GdkWindowObject *obj;
-
-  obj = (GdkWindowObject *) window;
-  impl = GDK_WINDOW_IMPL_X11 (obj->impl);
-
-  impl->position_info.no_bg = TRUE;
-
-  if (obj->bg_pixmap != GDK_NO_BG)
-    XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
-                               GDK_DRAWABLE_XID (window), None);
-}
-
-static void
-gdk_window_tmp_reset_bg (GdkWindow *window)
-{
-  GdkWindowImplX11 *impl;
-  GdkWindowObject *obj;
-
-  obj = (GdkWindowObject *) window;
-  impl = GDK_WINDOW_IMPL_X11 (obj->impl);
-
-  impl->position_info.no_bg = FALSE;
-
-  if (obj->bg_pixmap == GDK_NO_BG)
-    return;
-  
-  if (obj->bg_pixmap)
-    {
-      Pixmap xpixmap;
-
-      if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG)
-       xpixmap = ParentRelative;
-      else 
-       xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap);
-
-      XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
-                                 GDK_DRAWABLE_XID (window), xpixmap);
-    }
-  else
-    {
-      XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window),
-                           GDK_DRAWABLE_XID (window),
-                           obj->bg_color.pixel);
-    }
-}
-
 static void
 gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle *new_clip)
 {
@@ -1145,7 +1094,7 @@ gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle
   gdk_region_subtract (new_clip_region, old_clip_region);
   if (!gdk_region_empty (new_clip_region))
     {
-      gdk_window_tmp_unset_bg (window);
+      _gdk_x11_window_tmp_unset_bg (window, FALSE);;
       gdk_window_invalidate_region (window, new_clip_region, FALSE);
     }
 
index e764de8ff8571c3e4fc3ed8960903b2f2d80d227..0214177f415bca6d36229f35227abbd5a4388f37 100644 (file)
@@ -217,6 +217,118 @@ gdk_window_impl_x11_finalize (GObject *object)
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+static void
+tmp_unset_bg (GdkWindow *window)
+{
+  GdkWindowImplX11 *impl;
+  GdkWindowObject *obj;
+
+  obj = (GdkWindowObject *) window;
+  impl = GDK_WINDOW_IMPL_X11 (obj->impl);
+
+  impl->position_info.no_bg = TRUE;
+
+  if (obj->bg_pixmap != GDK_NO_BG)
+    XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
+                               GDK_DRAWABLE_XID (window), None);
+}
+
+static void
+tmp_reset_bg (GdkWindow *window)
+{
+  GdkWindowImplX11 *impl;
+  GdkWindowObject *obj;
+
+  obj = (GdkWindowObject *) window;
+  impl = GDK_WINDOW_IMPL_X11 (obj->impl);
+
+  impl->position_info.no_bg = FALSE;
+
+  if (obj->bg_pixmap == GDK_NO_BG)
+    return;
+  
+  if (obj->bg_pixmap)
+    {
+      Pixmap xpixmap;
+
+      if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG)
+       xpixmap = ParentRelative;
+      else 
+       xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap);
+
+      XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
+                                 GDK_DRAWABLE_XID (window), xpixmap);
+    }
+  else
+    {
+      XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window),
+                           GDK_DRAWABLE_XID (window),
+                           obj->bg_color.pixel);
+    }
+}
+
+void
+_gdk_x11_window_tmp_unset_bg (GdkWindow *window,
+                             gboolean   recurse)
+{
+  GdkWindowObject *private;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+  private = (GdkWindowObject *)window;
+
+  if (private->input_only || private->destroyed || !GDK_WINDOW_IS_MAPPED (window))
+    return;
+
+  /* Don't unset the background of windows that don't select for expose
+   * events. Such windows don't get drawn, so we need the X server
+   * drawing them to prevent them from containing garbage
+   */
+  if (private->window_type != GDK_WINDOW_ROOT &&
+      private->window_type != GDK_WINDOW_FOREIGN &&
+      (private->event_mask & GDK_EXPOSURE_MASK))
+    {
+      tmp_unset_bg (window);
+    }
+
+  if (recurse)
+    {
+      GList *l;
+
+      for (l = private->children; l != NULL; l = l->next)
+       _gdk_x11_window_tmp_unset_bg (l->data, TRUE);
+    }
+}
+
+void
+_gdk_x11_window_tmp_reset_bg (GdkWindow *window,
+                             gboolean   recurse)
+{
+  GdkWindowObject *private;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  private = (GdkWindowObject *)window;
+
+  if (private->input_only || private->destroyed || !GDK_WINDOW_IS_MAPPED (window))
+    return;
+
+  if (private->window_type != GDK_WINDOW_ROOT &&
+      private->window_type != GDK_WINDOW_FOREIGN &&
+      (private->event_mask & GDK_EXPOSURE_MASK))
+    {
+      tmp_reset_bg (window);
+    }
+
+  if (recurse)
+    {
+      GList *l;
+
+      for (l = private->children; l != NULL; l = l->next)
+       _gdk_x11_window_tmp_reset_bg (l->data, TRUE);
+    }
+}
+
 static GdkColormap*
 gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
 {
@@ -987,6 +1099,14 @@ _gdk_windowing_window_destroy_foreign (GdkWindow *window)
   gdk_error_trap_pop ();
 }
 
+static GdkWindow *
+get_root (GdkWindow *window)
+{
+  GdkScreen *screen = gdk_drawable_get_screen (window);
+
+  return gdk_screen_get_root_window (screen);
+}
+
 /* This function is called when the XWindow is really gone.
  */
 void
@@ -1227,6 +1347,7 @@ show_window_internal (GdkWindow *window,
               impl->override_redirect) &&
              gdk_window_is_viewable (window))
            {
+             _gdk_x11_window_tmp_reset_bg (window, TRUE);
              gdk_window_invalidate_rect (window, NULL, TRUE);
            }
        }
@@ -1277,6 +1398,55 @@ gdk_window_show (GdkWindow *window)
   show_window_internal (window, TRUE);
 }
 
+static void
+pre_unmap (GdkWindow *window)
+{
+  GdkWindow *start_window = NULL;
+  GdkWindowObject *private = (GdkWindowObject *)window;
+
+  if (private->input_only)
+    return;
+
+  if (private->window_type == GDK_WINDOW_CHILD)
+    start_window = (GdkWindow *)private->parent;
+  else if (private->window_type == GDK_WINDOW_TEMP)
+    start_window = get_root (window);
+
+  if (start_window)
+    _gdk_x11_window_tmp_unset_bg (start_window, TRUE);
+}
+
+static void
+post_unmap (GdkWindow *window)
+{
+  GdkWindow *start_window = NULL;
+  GdkWindowObject *private = (GdkWindowObject *)window;
+  
+  if (private->input_only)
+    return;
+
+  if (private->window_type == GDK_WINDOW_CHILD)
+    start_window = private->parent;
+  else if (private->window_type == GDK_WINDOW_TEMP)
+    start_window = get_root (window);
+
+  if (start_window)
+    {
+      _gdk_x11_window_tmp_reset_bg (start_window, TRUE);
+
+      if (private->window_type == GDK_WINDOW_CHILD && private->parent)
+       {
+         GdkRectangle invalid_rect;
+      
+         gdk_window_get_position (window, &invalid_rect.x, &invalid_rect.y);
+         gdk_drawable_get_size (GDK_DRAWABLE (window),
+                                &invalid_rect.width, &invalid_rect.height);
+         gdk_window_invalidate_rect ((GdkWindow *)private->parent,
+                                     &invalid_rect, TRUE);
+       }
+    }
+}
+
 /**
  * gdk_window_hide:
  * @window: a #GdkWindow
@@ -1329,9 +1499,13 @@ gdk_window_hide (GdkWindow *window)
       g_assert (!GDK_WINDOW_IS_MAPPED (window));
       
       _gdk_window_clear_update_area (window);
+
+      pre_unmap (window);
       
       XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
                     GDK_WINDOW_XID (window));
+
+      post_unmap (window);
     }
 }
 
@@ -1360,9 +1534,13 @@ gdk_window_withdraw (GdkWindow *window)
                                      GDK_WINDOW_STATE_WITHDRAWN);
 
       g_assert (!GDK_WINDOW_IS_MAPPED (window));
+
+      pre_unmap (window);
       
       XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
                        GDK_WINDOW_XID (window), 0);
+
+      post_unmap (window);
     }
 }
 
index 4e726f4b80e08bac2ce48f389344b92e7dcba05a..e2f160bd73aa20b31a1496375b887465d93e11be 100644 (file)
@@ -127,6 +127,11 @@ GType gdk_window_impl_x11_get_type (void);
 GdkToplevelX11 *_gdk_x11_window_get_toplevel  (GdkWindow *window);
 void             gdk_x11_window_set_user_time (GdkWindow *window,
                                                guint32    timestamp);
+void           _gdk_x11_window_tmp_unset_bg  (GdkWindow *window,
+                                              gboolean   recurse);
+void            _gdk_x11_window_tmp_reset_bg  (GdkWindow *window,
+                                              gboolean   recurse);
+
 
 G_END_DECLS